#! /bin/ksh
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
#  
#  
# Licensed Materials - Property of IBM 
#  
# (C) COPYRIGHT International Business Machines Corp. 2001,2004 
# All Rights Reserved 
#  
# US Government Users Restricted Rights - Use, duplication or 
# disclosure restricted by GSA ADP Schedule Contract with IBM Corp. 
#  
# IBM_PROLOG_END_TAG 

# "@(#)55   1.5   src/rsct/utils/ctinitmgr.sh, common_utils, rsct_rzauh, rzauh0431a 11/26/02 01:51:23"

#########################################################################
#                                                                       #
# RSCT init script manager for major Linux distributions                #
#                                                                       #
# Syntax:                                                               #
#     ctinitmgr -a init_script [-b [0|1]] | -d service_name             #
#     ctinitmgr {-s | -k} service_name                                  #
#                                                                       #
#     -a add init_script as the init script of service_name             #
#     -b used in conjunction with -a to specify if the service should   #
#        be started or not. 0 means the service is not started in any   #
#        runlevel. 1 means the service should be started in the         #
#        runlevels specified in the init_script.                        #
#        Note: changing the symbolic links in rc?.d/ is deprecated      #
#        since insserv used in SuSE creates them dynamically based on   #
#        the dependency between SysV init scripts. Services started at  #
#        boot time conditionally should check the condition in its SysV #
#        init script.                                                   #
#     -d delete service_name from the init script directory             #
#     -k mark the service "stopped" (so it won't be kill again)         #
#     -s mark the service "started" (so it can be killed at runlevel 0) #
#                                                                       #
#     System administration is distribution dependent. Every Linux      #
#     distributor can have its own init script structure. Major Linux   #
#     distributors, e.g. RedHat, use System V style init script         #
#     structure:                                                        #
#                                                                       #
#     SYSVINIT_ROOT                                                     #
#        |--- rc.sysinit                                                #
#        |--- rc.local                                                  #
#        |--- init.d/                                                   #
#        |--- rc0.d/                                                    #
#        |--- rc1.d/                                                    #
#        |--- rc2.d/                                                    #
#        |--- rc3.d/                                                    #
#        |--- rc4.d/                                                    #
#        |--- rc5.d/                                                    #
#        |--- rc6.d/                                                    #
#                                                                       #
#     SYSVINIT_ROOT is /etc, /sbin/rc.d or /etc/rc.d. The services put  #
#     a contorl script in init.d/ and symbolic links are made from      #
#     init.d/service to rc?.d/[KS][0-9][0-9]service. When the system    #
#     enters run level R, rc$R.d/K* are run with "stop" first and       #
#     then rc$R.d/S* are run with "start". Various tools can are used   #
#     to manage the structure. For example, chkconfig is used by        #
#     RedHat and insserv is used by SuSE.                               #
#                                                                       #
#     Some tools, e.g. chkconfig, needs the run level and the two-digit #
#     sequence numbers be specified in the init_script using special    #
#     keywords in the comments. These special keywords look like        #
#     comments to the shell but can be recognized by the tool.          #
#     Check the man pages of these tools when writing init scripts.     #
#     To work with the different init script management tools, RSCT     #
#     init scripts, e.g. rc_ctrmc, needs to be compatible with all      #
#     init script management tools used in major Linux distributions.   #
#                                                                       #
#     The run level definition is almost identical in all major Linux   #
#     distributions. However, the two-digit sequence numbers may vary   #
#     between distributions. Some tools even arrange the sequence       #
#     by analizing the dependency between services.                     #
#     This script will use the RedHat chkconfig format to determine the #
#     sequence numbers when no tool is used.                            #
#                                                                       #
#     The steps of the boot are as following:                           #
#         - the kernel runs init                                        #
#         - init runs $SYSVINIT_ROOT/rc.sysinit                         #
#         - rc.sysinit does a bunch of necessary things, mostly         #
#           extra hardware initialization (modules), check filesystems, #
#           set time, ... etc.                                          #
#         - init runs rc.local                                          #
#         - init runs all the scripts for the default runlevel.         #
#                                                                       #
#     Some distrinutons, e.g. older SuSE (7.0 and earlier), puts rc?.d/ #
#     under init.d/.                                                    #
#                                                                       #
# Examples:                                                             #
#                                                                       #
#     1. To add /usr/sbin/rsct/bin/rc_ctrmc to be the init script of    #
#        ctrmc service, enter:                                          #
#                                                                       #
#        ctinitmgr -a /usr/sbin/rsct/bin/rc_ctrmc ctrmc                 #
#                                                                       #
#     2. To add /usr/sbin/rsct/bin/rc.cthats to be the init script of   #
#        cthats service and do not start cthats in any runlevel, enter: #
#                                                                       #
#        ctinitmgr -a /usr/sbin/rsct/bin/rc.cthats cthats -b 0          #
#                                                                       #
#     3. To remove cthatsgs service from the init script directory,     #
#        enter:                                                         #
#                                                                       #
#        ctinitmgr -d cthatsgs                                          #
#                                                                       #
#     4. To mark ctrmc as "started", enter:                             #
#                                                                       #
#        ctinitmgr -s ctrmc                                             #
#                                                                       #
#     5. To mark ctrmc as "stopped", enter:                             #
#                                                                       #
#        ctinitmgr -k ctrmc                                             #
#                                                                       #
#########################################################################

#=======================================================================#
#                                                                       #
# To add a new distribution:                                            #
#  1. Global variables $init_script contains the location of the init   #
#     script to be added and $service_name contains the service name    #
#     to be used. For example, RMC's init script is in                  #
#     /usr/sbin/rsct/bin/rc_ctrmc and its service name is ctrmc.        #
#     The $init_script and $service_name are passed in by command line  #
#     option of this script.                                            #
#                                                                       #
#  2. Add a new subroutine called is_xxxx. Where xxxx is the name of    #
#     Linux distribution. e.g. is_RedHat. This subroutine should        #
#     return 0 if it identifies the system is using the xxxx Linux      #
#     distribution and 1 if it is not. Some Linux distributions put     #
#     a release file in the system so that the distribution name can be #
#     easily identified. e.g. RedHat has /etc/redhat-release. However,  #
#     other Linux distributions do not have the release file and have   #
#     to be identified by other way.                                    #
#     In addition to the return code, is_xxxx() can optionally set      #
#     $init_root to the root directory of the System V init scripts.    #
#     e.g. /etc/rc.d                                                    #
#                                                                       #
#  3. Add a new subroutine called add_xxxx. This subroutine adds the    #
#     service to the init script structure. 0 should be returned when   #
#     the service is added successfully, 1 otherwise.                   #
#     $init_root can be used in add_xxxx() if it is set in is_xxxx().   #
#                                                                       #
#  4. Add a new subroutine called delete_xxxx. This subroutine deletes  #
#     the service from the init script structure. 0 should be returned  #
#     when the service is deleted successfully, 1 otherwise.            #
#     $init_root can be used in delete_xxxx() if it is set in is_xxxx().#
#                                                                       #
#  5. Add a new subroutine called reg_start_xxxx(). This subroutine     #
#     registers the service as "started". 0 should be returned when     #
#     the service is registered successfully, 1 otherwise.              #
#     $init_root can be used in reg_start_xxxx() if it is set.          #
#     Note that reg_start_xxxx() could be called even when the service  #
#     is running. Checking is required before registering the service.  #
#                                                                       #
#  6. Add a new subroutine called reg_kill_xxxx(). This subroutine      #
#     registers the service as "stopped". 0 should be returned when     #
#     the service is registered successfully, 1 otherwise.              #
#     $init_root can be used in reg_start_xxxx() if it is set.          #
#     Note that reg_kill_xxxx() could be called even when the service   #
#     is not active. Checking is required before un-registering the     #
#     service.                                                          #
#                                                                       #
#  7. Global variable $DISTRIBUTIONS located at the beginning of main   #
#     program contains the names of supported Linux distributions.      #
#     The new xxxx Linux distribution needs to be added to the          #
#     variable. The Linux distribution name xxxx must match the         #
#     subroutine names is_xxxx(), add_xxxx(), and delete_xxxx().        #
#     The order of the distribution names in $DISTRIBUTIONS is          #
#     important. is_xxxx() are called following the order in            #
#     $DISTRIBUTIONS and the first one returning 0 is picked up.        #
#     Always put tightly checked is_xxxx() before loosely checked       #
#     is_xxxx(). For example, any system uses System V style init can   #
#     be identified as UnknownSysV. RedHat uses System V style init.    #
#     Putting UnknownSysV before RedHat will cause RedHat distribution  #
#     be identified as UnknownSysV instead of RedHat.                   #
#                                                                       #
#=======================================================================#

#=======================================================================#
#                                                                       #
# Function: parse_chkconfig_setting                                     #
# Description: determine the run level and sequence numbers using       #
#     chkconfig format from the init script.                            #
#                                                                       #
# Upon the following variables are set:                                 #
#    s_levels: the runlevels that the service should be started. The    #
#        runlevels are separated by a space.                            #
#    k_sequence: the 2-digit sequence number used to stop the service   #
#    s_sequence: the 2-digit sequence number used to start the service  #
#                                                                       #
# Return code:                                                          #
#     0: successful, $s_levels contains the run levels the init script  #
#        should be started, $k_sequence/$s_sequence contain the         #
#        sequence numbers when the init script is stopped/started.      #
#     1: error                                                          #
#                                                                       #
#=======================================================================#

parse_chkconfig_setting() {
    #set -x
    RC_parse_chkconfig_setting=0
    # Looking for chkconfig signature in the init script.
    # e.g. "# chkconfig: 345 32 68". It is easier to use read to get the
    # run levels and sequence numbers. Unfortunately, ksh read does nor
    # work as expected. See known bugs in pdksh document.
    # First we remove the chkconfig signature
    chkconfig_setting=`grep "# *chkconfig:" $init_script | \
        sed "s/^.*# *chkconfig: *//"`
    # The run level can be '-' or digits. The sequence numbers are 2-digits.
    # Note sed does not handle X+. Need to use XX* instead.
    s_levels=`echo $chkconfig_setting | \
        sed "s/\([-0-6]*\)  *\([0-9][0-9]\)  *\([0-9][0-9]\)/\1/"`
    s_sequence=`echo $chkconfig_setting | \
        sed "s/\([-0-6]*\)  *\([0-9][0-9]\)  *\([0-9][0-9]\)/\2/"`
    k_sequence=`echo $chkconfig_setting | \
        sed "s/\([-0-6]*\)  *\([0-9][0-9]\)  *\([0-9][0-9]\)/\3/"`

    # Make sure $s_levels, $k_sequence, $s_sequence all have values
    if [[ "X$s_levels" != X && "X$k_sequence" != X && "X$s_sequence" != X ]]
    then
        # $s_levels is "-" if the script is not started in any run level.
        if [[ "X$s_levels" = "X-" ]]
        then
            s_levels=""
        fi
    else
        RC_parse_chkconfig_setting=1
    fi
    return $RC_parse_chkconfig_setting
}

#=======================================================================#
#                                                                       #
# Function: chk_rc_d_dir                                                #
# Description: Check if the rc?.d/ subdirectories exist in the          #
#     directory specified in the first parameter.                       #
#                                                                       #
# Return:                                                               #
#     0: rc?.d/ subdirectories are found.                               #
#     1: rc?.d/ subdirectories are not found.                           #
#                                                                       #
#=======================================================================#

chk_rc_d_dir() {
    #set -x
    for i_chk_rc_d_dir in $RUN_LEVELS
    do
        if [[ ! -d $1/rc${i_chk_rc_d_dir}.d ]]
        then
            return 1
        fi
    done
    return 0
}

#=======================================================================#
#                                                                       #
# Function: is_RedHat, add_RedHat, delete_RedHat, reg_start_RedHat,     #
#     reg_kill_RedHat
# Description: RedHat identification and init script management         #
#     RedHat Linux distribution can be identified by checking RedHat    #
#     release file /etc/redhat-release.                                 #
#     /etc/redhat-release contains the RedHat release numbers and name. #
#     /etc/redhat-release is in redhat-release rpm. All RedHat systems  #
#     should have this file.                                            #
#     RedHat uses chkconfig to manage the init scripts.                 #
#     RedHat check the presence of /var/lock/subsys/$service_name befor #
#     running the scripts in rc?.d/. /var/lock/subsys/$service_name     #
#     should be created as soon as the service is up and deleted as     #
#     soon as the service is down.                                      #
#                                                                       #
#=======================================================================#

is_RedHat() {
    if [[ -f /etc/redhat-release && -x /sbin/chkconfig ]]
    then
        init_root=/etc/rc.d
        return 0
    else
        return 1
    fi
}

#-----------------------------------------------------------------------

add_RedHat() {
    #set -x
    # Clean up old setup
    delete_RedHat

    RC_add_RedHat=0
    if ln -f -s $init_script $init_root/init.d/$service_name
    then
        if chkconfig --add $service_name
        then
            if (( $allow_start == 0 ))
            then
                # Turn off the service in all runlevels.
                chkconfig --level $RUN_LEVELS_PACKED $service_name off
            fi
        else
            RC_add_RedHat=1
        fi
    else
        RC_add_RedHat=1
    fi
    return $RC_add_RedHat
}

#-----------------------------------------------------------------------

delete_RedHat() {
    #set -x
    RC_delete_RedHat=0
    if [[ -f $init_root/init.d/$service_name ]]
    then
        if chkconfig --del $service_name
        then
            if ! rm -f $init_root/init.d/$service_name
            then
                RC_delete_RedHat=1
            fi
        else
            RC_delete_RedHat=1
        fi
    fi
    return $RC_delete_RedHat
}

#-----------------------------------------------------------------------

reg_start_RedHat() {
    #set -x
    RC_reg_start_RedHat=0
    if [[ ! -f /var/lock/subsys/$service_name ]]
    then
        if ! touch /var/lock/subsys/$service_name
        then
            RC_reg_start_RedHat=1
        fi
    fi
    return $RC_reg_start_RedHat
}

#-----------------------------------------------------------------------

reg_kill_RedHat() {
    #set -x
    RC_reg_kill_RedHat=0
    if [[ -f /var/lock/subsys/$service_name ]]
    then
        if ! rm -f /var/lock/subsys/$service_name
        then
            RC_reg_kill_RedHat=1
        fi
    fi
    return $RC_reg_kill_RedHat
}
 
#=======================================================================#
#                                                                       #
# Function: is_Stingray, add_Stingray, delete_Stingray,                 #
#     reg_start_Stingray, reg_kill_Stingray                             #
# Description: Stingray identification and init script management       #
#     Stingray is the system used by NAS. It is a stript system that    #
#     contains only necessary files for NAS applications. The Stingray  #
#     system can be identified by checking the existance of its server  #
#     program /bin/ms_server. Stingray system can use /sbin/chkconfig   #
#     to manage its SysV init script structure. It also uses            #
#     /var/lock/subsys/$service_name to indicate if the subsystem is up #
#     or not. The Stingray init script structure is very similar to     #
#     RedHat. We can use RedHat functions for Stingray systems.         #
#                                                                       #
#=======================================================================#

is_Stingray() {
    if [[ -f /bin/ms_server && -x /sbin/chkconfig ]] 
    then                       
        init_root=/etc/rc.d     
        return 0               
    else
        return 1
    fi
}

#-----------------------------------------------------------------------

add_Stingray() {
    add_RedHat
    return $?
}

#-----------------------------------------------------------------------

delete_Stingray() {
    delete_RedHat
    return $?
}

#-----------------------------------------------------------------------

reg_start_Stingray() {
    reg_start_RedHat
    return $?
}

#-----------------------------------------------------------------------

reg_kill_Stingray() {
    reg_kill_RedHat
    return $?
}

#=======================================================================#
#                                                                       #
# Function: is_TurboLinux, add_TurboLinux, delete_TurboLinux            #
#     reg_start_TurboLinux, reg_kill_TurboLinux                         #
# Description: TurboLinux identification and init script management     #
#     TurboLinux distribution can be identified by checking TurboLinux  #
#     release file /etc/turbolinux-release.                             #
#     /etc/turbolinux-release contains the TurboLinux release numbers.  #
#     /etc/turbolinux-release is in turbolinux-release-{wks,srv} rpm.   #
#     All TurboLinux system should have this file.                      #
#     Like RedHat, TurboLinux uses chkconfig to manage the init scripts.#
#     TurboLinux check the presence of /var/lock/subsys/$service_name   #
#     running the scripts in rc?.d/. /var/lock/subsys/$service_name     #
#     should be created as soon as the service is up and deleted as     #
#     soon as the service is down.                                      #
#                                                                       #
#=======================================================================#

is_TurboLinux() {
    if [[ -f /etc/turbolinux-release && -x /sbin/chkconfig ]]
    then
        init_root=/etc/rc.d
        return 0
    else
        return 1
    fi
}

#-----------------------------------------------------------------------

add_TurboLinux() {
    add_RedHat
    return $?
}

#-----------------------------------------------------------------------

delete_TurboLinux() {
    delete_RedHat
    return $?
}

#-----------------------------------------------------------------------

reg_start_TurboLinux() {
    reg_start_RedHat
    return $?
}

#-----------------------------------------------------------------------

reg_kill_TurboLinux() {
    reg_kill_RedHat
    return $?
}

#=======================================================================#
#                                                                       #
# Function: is_SuSE, add_SuSE, delete_SuSE, reg_start_SuSE,             #
#     reg_kill_SuSE                                                     #
# Description: SuSE identification and init script management           #
#     SuSE Linux distribution can be identified by checking SuSE        #
#     release file /etc/SuSE-release.                                   #
#     /etc/SuSE-release contains the SuSE release numbers.              #
#     /etc/SuSE-release is in aaa_base rpm. All SuSE system should      #
#     have this file.                                                   #
#     Starting 7.1, SuSE uses insserv to manage the init scripts.       #
#     SuSE 7.0 and earlier releases does not use insserv and the init   #
#     scripts are in /sbin/init.d. The subroutines is_SuSE, add_SuSE,   #
#     and delete_SuSE deal with new SuSE (7.1) with insserv. Older SuSE #
#     releases are handled as UnknownSysV.                              #
#     SuSE does not check anything before running the scripts in rc?.d. #
#     reg_start_SuSE() and reg_kill_SuSE() always return 0.             #
#                                                                       #
#=======================================================================#

is_SuSE() {
    if [[ -f /etc/SuSE-release && -x /sbin/insserv && -d /etc/init.d ]]
    then
        init_root=/etc
        return 0
    else
        return 1
    fi
}

#-----------------------------------------------------------------------

add_SuSE() {
    #set -x
    # Clean up old setup
    delete_SuSE

    RC_add_SuSE=0
    if ln -f -s $init_script $init_root/init.d/$service_name
    then
        insserv $init_root/init.d/$service_name 2> /dev/null
        if [[ $? -ne 0 ]]
        then
            RC_add_SuSE=1
        fi
        if (( $allow_start == 0 ))
        then
            print -u2 "$SCRIPT: -b option does not work for SuSE 7.1 and newer"
            RC_add_SuSE=1
        fi
    else
        RC_add_SuSE=1
    fi
    return $RC_add_SuSE
}

#-----------------------------------------------------------------------

delete_SuSE() {
    #set -x
    RC_delete_SuSE=0
    if [[ -f $init_root/init.d/$service_name ]]
    then
        insserv -r $init_root/init.d/$service_name 2> /dev/null
        if [[ $? -eq 0 ]]
        then
            if ! rm -f $init_root/init.d/$service_name
            then
                RC_delete_SuSE=1
            fi
        else
            RC_delete_SuSE=1
        fi
    fi
    return $RC_delete_SuSE
}

#-----------------------------------------------------------------------

reg_start_SuSE() {
    return 0
}

#-----------------------------------------------------------------------

reg_kill_SuSE() {
    return 0
}

#=======================================================================#
#                                                                       #
# !!! These subroutines have not been throughly tested yet !!!          #
# Function: is_Caldera, add_Caldera, delete_Caldera, reg_start_Caldera, #
#     reg_kill_Caldera                                                  #
# Description: Caldera identification and init script management        #
#     Caldera Linux distribution can be identified by checking the      #
#     system administration tool configuration files /etc/system.cnf    #
#     and /etc/lst.conf.                                                #
#     Caldera uses lisa to manage the init scripts.                     #
#     /etc/system.cnf and /etc/lst.conf are the configuration files     #
#     used by the Linux Support Team, LST, distribution.                #
#     LST distribution is the base of Caldera Open Linux Distribution.  #
#     /etc/system.cnf and /etc/lst.conf are in lisa rpm. All Caldera    #
#     systems should have these files.                                  #
#     Caldera does not check anything before running the scripts in     #
#     rc?.d. reg_start_Caldera() and reg_kill_Caldera() always return 0.#
#                                                                       #
#=======================================================================#

is_Caldera() {
    if [[ -f /etc/system.cnf && -f /etc/lst.conf && -x /bin/lisa ]]
    then
        init_root=/etc/rc.d     # This is controled by DIR_INIT_CONF in lst.conf
        return 0
    else
        return 1
    fi
}

#-----------------------------------------------------------------------

add_Caldera() {
    #set -x
    # Clean up old setup
    delete_Caldera

    RC_add_Caldera=0
    if ln -f -s $init_script $init_root/init.d/$service_name
    then
        # Find K/S sequence numbers for each run level
        parse_chkconfig_setting
        if [[ $? -eq 0 ]]
        then
            if (( $allow_start == 0 ))
            then
                # Force not to start the service in any runlevel. 
                s_levels=""
            fi
            # lisa syntax looks like:
            #     lisa --SysV-init install ctrmc S32 2:3:4:5 K68 0:1:6 
            # Find run levels to start/stop the service and separate 
            # them with ':'. e.g. $s_level looks like ":2:3:4:5".
            lisa_k_level=""
            lisa_s_level=""
            for i in $RUN_LEVELS
            do
                echo $s_levels | grep "$i" > /dev/null 2>&1
                if [[ $? -eq 0 ]]
                then
                    lisa_s_level="$lisa_s_level:$i"
                else
                    lisa_k_level="$lisa_k_level:$i"
                fi
            done
            # The following two if blocks turn ":2:3:4:5" to something
            # like "S32 2:3:4:5".
            if [[ "X$lisa_k_level" != "X" ]]
            then
                k_str=`echo $lisa_k_level | sed "s/^:/K$k_sequence /"`
            else
                k_str=""
            fi
            if [[ "X$lisa_s_level" != "X" ]]
            then
                s_str=`echo $lisa_s_level | sed "s/^:/S$s_sequence /"`
            else
                s_str=""
            fi
            # Issue lisa command to add the service
            if ! lisa --SysV-init install $service_name $s_str $k_str
            then
                RC_add_Caldera=1
            fi
        fi
    else
        RC_add_Caldera=1
    fi
    return $RC_add_Caldera
}

#-----------------------------------------------------------------------

delete_Caldera() {
    #set -x
    RC_delete_Caldera=0
    if [[ -f $init_root/init.d/$service_name ]]
    then
        if lisa --SysV-init remove $service_name
        then
            if ! rm -f $init_root/init.d/$service_name
            then
                RC_delete_Caldera=1
            fi
        else
            RC_delete_Caldera=1
        fi
    fi
    return $RC_delete_Caldera
}

#-----------------------------------------------------------------------

reg_start_Caldera() {
    return 0
}

#-----------------------------------------------------------------------

reg_kill_Caldera() {
    return 0
}

#=======================================================================#
#                                                                       #
# Function: is_UnknownSysV, add_UnknownSysV, delete_UnknownSysV         #
#     reg_start_UnknownSysV, reg_kill_UnknownSysV                       #
# Description: System V style init identification and management        #
#     System V style init can be identified by checking the directory   #
#     structure described in the beginning of this file. No init script #
#     management tool is used here. However, to determine which run     #
#     level to start/stop the service and the sequence numbers,         #
#     add_UnknownSysV() uses the setting of chkconfig in the init       #
#     script.                                                           #
#     Note that other supported distributions may be recognized by      #
#     is_UnknownSysV() if they use System V style init scripts.         #
#     Always put UnknownSysV as the last System V distribution name in  #
#     $DISTRIBUTIONS.                                                   #
#     It is hard to determine what should be done when a service is up  #
#     or down if we don't know what Linux distribution we are using.    #
#     RedHat and TurboLinux use /var/lock/subsys/$service_name to       #
#     determine if a service is up. We put one if /var/lock/subsys/     #
#     exists.                                                           #
#                                                                       #
#=======================================================================#

is_UnknownSysV() {
    for i in $SYSVINIT_ROOT_ALL
    do
        if [[ -d $i && -d $i/init.d ]]
        then
            # Check rc?.d/ in $i/ (Most distributions)
            chk_rc_d_dir $i
            if [[ $? -eq 0 ]]
            then
                init_root=$i
                return 0
            fi
            # Check rc?.d/ in $i/init.d/ (SuSE 7.0 and earlier)
            chk_rc_d_dir $i/init.d
            if [[ $? -eq 0 ]]
            then
                init_root=$i
                return 0
            fi
        fi
    done
    return 1
}

#-----------------------------------------------------------------------

add_UnknownSysV() {
    #set -x
    # Clean up old setup
    delete_UnknownSysV

    RC_add_UnknownSysV=0
    if ln -f -s $init_script $init_root/init.d/$service_name
    then
        # Find K/S sequence numbers for each run level
        parse_chkconfig_setting
        if [[ $? -eq 0 ]]
        then
            if (( $allow_start == 0 ))
            then
                # Force not to start the service in any runlevel.
                s_levels=""
            fi

            chk_rc_d_dir $init_root/init.d
            if [[ $? -eq 0 ]]
            then
                rc_d_dir=$init_root/init.d      # absolute path of rc?.d/
                init_d_relative=..              # relative path to init.d/
            else
                rc_d_dir=$init_root             # absolute path of rc?.d/
                init_d_relative=../init.d       # relative path to init.d/
            fi
    
            for i in $RUN_LEVELS
            do
                # Set K/S and sequence numbers for each run level
                echo $s_levels | grep "$i" > /dev/null 2>&1
                if [[ $? -eq 0 ]]
                then
                    rl_seq="rc$i.d/S$s_sequence"
                else
                    rl_seq="rc$i.d/K$k_sequence"
                fi
                # Make symbolic link from init.d/ to rc?.d/
                if ! ln -f -s $init_d_relative/$service_name \
                    $rc_d_dir/$rl_seq$service_name
                then
                    RC_add_UnknownSysV=1
                fi
            done
        else
            # chkconfig signature is not found in the init script.
            RC_add_UnknownSysV=1
        fi
    else
        # Cannot make a symbolic link to
        # $init_root/init.d/$service_name
        RC_add_UnknownSysV=1
    fi
    return $RC_add_UnknownSysV
}

#-----------------------------------------------------------------------

delete_UnknownSysV() {
    #set -x
    RC_delete_UnknownSysV=0
    if [[ -f $init_root/init.d/$service_name ]]
    then
        chk_rc_d_dir $init_root/init.d
        if [[ $? -eq 0 ]]
        then
            rc_d_dir=$init_root/init.d
        else
            rc_d_dir=$init_root
        fi
        # "rm -f" is "successful" if the file to be removed does not exist.
        if ! rm -f $rc_d_dir/rc?.d/[KS][0-9][0-9]$service_name \
            $init_root/init.d/$service_name
        then
            RC_delete_UnknownSysV=1
        fi
    fi
    return $RC_delete_UnknownSysV
}

#-----------------------------------------------------------------------

reg_start_UnknownSysV() {
    #set -x
    RC_reg_start_UnknownSysV=0
    if [[ -d /var/lock/subsys/ ]]
    then
        if [[ ! -f /var/lock/subsys/$service_name ]]
        then
            if ! touch /var/lock/subsys/$service_name
            then
                $RC_reg_start_UnknownSysV=1
            fi
        fi
    fi
    return $RC_reg_start_UnknownSysV
}

#-----------------------------------------------------------------------

reg_kill_UnknownSysV() {
    #set -x
    RC_reg_kill_UnknownSysV=0
    if [[ -f /var/lock/subsys/$service_name ]]
    then
        if ! rm -f /var/lock/subsys/$service_name
        then
            RC_reg_kill_UnknownSysV=1
        fi
    fi
    return $RC_reg_kill_UnknownSysV
}

#########################################################################
#                                                                       #
# ctinitmgr.sh main program starts here.                                #
#                                                                       #
#########################################################################

#set -x
RSCTBIN=/usr/sbin/rsct/bin
export PATH=/bin:/sbin:/usr/bin:/usr/sbin:${RSCTBIN}
SCRIPT=$(basename $0)
RUN_LEVELS="0 1 2 3 4 5 6"
RUN_LEVELS_PACKED="0123456"
# Possible System V init script root directories.
# /etc: Linux Standard Base (LSB) specification, SuSE 7
# /etc/rc.d: RedHat
# /sbin: Older SuSE
SYSVINIT_ROOT_ALL="/etc /etc/rc.d /sbin /sbin/rc.d"
# Put specific ones in front of the general ones so that the specific ones
# can be identified. For example, UnknownSysV is the most generic one and
# should be put in the last of the list.
DISTRIBUTIONS="Stingray RedHat TurboLinux SuSE Caldera UnknownSysV"

#
# Parse command line options
#

Argcount=0
allow_start=1                   # By defeult, services can be started according
                                # to the settings in their init scripts.
while getopts ":a:b:dks" opt
do
    case $opt in
    a ) Op=add
        Argcount=$((Argcount + 1))
        init_script="$OPTARG"
        ;;
    d ) Op=delete 
        Argcount=$((Argcount + 1))
        ;;
    b ) # Valid value for -b are 0 and 1. All non-0 values are treated as 1.
        if (( $OPTARG == 0 ))
        then
            allow_start=0
        else
            allow_start=1
        fi
        # -b is a sub-option of -a. Do not increase $Argcount.
        ;;
    s ) Op=reg_start
        Argcount=$((Argcount + 1))
        ;;
    k ) Op=reg_kill
        Argcount=$((Argcount + 1))
        ;;
    ? ) print -u2 "$SCRIPT: Unknown command line flag -${OPTARG}\n"
        exit 1;;
    esac
done

if ((Argcount == 0))
then 
    print -u2 "$SCRIPT: Missing command line flag\n"
    exit 1
fi

if ((Argcount > 1))
then
    print -u2 "$SCRIPT: Only one command flag permitted\n"
    exit 1;
fi

shift $(($OPTIND -1))
service_name=$1

if [[ "X$service_name" = X ]]
then
    print -u2 "$SCRIPT: Missing service name.\n"
    exit 1
fi

shift

if [[ "X$1" != X ]]
then
    print -u2 "$SCRIPT: Extra arguments: $*\n"
    exit 1
fi

case $Op in
# Add/delete a service, register for starting/killing a service use similar code
add | delete | reg_start | reg_kill )
    for i_main in $DISTRIBUTIONS
    do
        is_$i_main
        if [[ $? -eq 0 ]]
        then
            ${Op}_$i_main
            exit $?
        fi
    done
    exit 1              # None of known init structure is found

    ;;

esac

exit 0

